﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include <vector>

#include "ExprEngineIntf.h"
#include "ExprTokenType.h"

namespace gcmp
{
    typedef union
    {
        bool BooleanValue;
        long int IntegerValue;
        double FloatValue;
        wchar_t StringValue[MAX_STRING_VALUE_LENGTH];
    }NodeValue;

    /// \brief 表达式节点数据
    class EXPR_ENGINE_API ExprCustumNodeData : public ExprNodeData
    {
    public:
        ExprCustumNodeData();
        virtual ~ExprCustumNodeData();
        ExprDataType GetType() const;
        void SetType(ExprDataType type);

        virtual UnitMap GetUnitType();
        virtual void SetUnitType(const UnitMap& unitType);

        void SetAsInteger(long aValue);
        long GetAsInteger() const;
        void SetAsBoolean(bool aValue);
        bool GetAsBoolean() const;
        void SetAsFloat(double aValue);
        double GetAsFloat() const;
        void SetAsString(const wchar_t* aValue);
        const wchar_t* GetAsString() const;

    private:
        NodeValue m_value;
        const ExprNode* m_pNode;
        ExprDataType m_dataType;
        UnitMap m_unitType;
        std::vector<wchar_t> m_externStringValue;
    };

    /// \brief 表达式语法树节点类
    class EXPR_ENGINE_API ExprCustumNode : public ExprNode
    {
    public:
        ExprCustumNode();
        ExprCustumNode(const ExprCustumNode& src);
        ExprCustumNode& operator=(const ExprCustumNode& src);
        virtual ~ExprCustumNode();

        ExprType GetNodeType() const;
        ExprNodeData* GetData();
        ExprDataType GetDataType() const;
        UnitMap GetUnitType();
        void SetTag(void* aTag);
        void* GetTag() const;

        ExprType m_nodeType; // 节点类型
        ExprCustumNodeData m_data;
        ExprTokenType m_token;
        int m_startPosition;
        int m_endPosition;
        gcmp::OwnerPtr<ExprNode> m_opLeftChild;
        gcmp::OwnerPtr<ExprNode> m_opRightChild;

    private:
        void* m_tag;
    };

    /// \brief 表达式语法树节点类（ID，需要由外部提供ID的类型和值）
    class EXPR_ENGINE_API ExprIDNode : public ExprCustumNode
    {
    public:
        ExprIDNode();
        ~ExprIDNode();
        void SetNodeCode(const wchar_t* aValue);
        const wchar_t* GetNodeCode() const;

    private:
        wchar_t m_stringValue[MAX_STRING_VALUE_LENGTH];
        std::vector<wchar_t> m_externStringValue;
    };

    /// \brief 函数参数列表
    class EXPR_ENGINE_API CustomFunctionParams : public FunctionParams
    {
    public:
        CustomFunctionParams();
        ~CustomFunctionParams();
        ExprNode* AppendParams(gcmp::OwnerPtr<ExprNode> aParam) override;
        short Count() const override;
        ExprNodeData* GetParam(short aIndex) override;
        const ExprNode* GetParamNode(short aIndex) const;
        ExprNode* GetParamNodeFW(short aIndex);

    private:
        CustomFunctionParams(const CustomFunctionParams& other);
        CustomFunctionParams& operator=(const CustomFunctionParams& other);

    private:
        std::vector<gcmp::OwnerPtr<ExprNode> > m_params;
        short  m_paramCount; // 参数个数
    };

    /// \brief 表达式语法树节点类（函数）
    class EXPR_ENGINE_API ExprFunctionNode : public ExprIDNode
    {
    public:
        ExprFunctionNode();
        virtual ~ExprFunctionNode();
        ExprNode* AppendParams(gcmp::OwnerPtr<ExprNode>& aParam);
        const CustomFunctionParams* GetParams() const;
        CustomFunctionParams* GetParamsFW();

    private:
        CustomFunctionParams m_params;
    };
}